package com.gitee.wsl.ext.array.bytes

import com.gitee.wsl.ext.base.ifValue
import com.gitee.wsl.lang.ByteOrder

/**
 * Get the set byte order/endianness. Default in Java is [ByteOrder.BIG_ENDIAN].
 *
 * either [ByteOrder.BIG_ENDIAN] or [ByteOrder.LITTLE_ENDIAN]
 * @see [Endianness](https://en.wikipedia.org/wiki/Endianness)
 */

fun Array<Byte>.bigEndianTo(byteOrder: ByteOrder) = (byteOrder == ByteOrder.BigEndian).ifValue(this,this.reversedArray())

fun ByteArray.bigEndianTo(byteOrder: ByteOrder) = (byteOrder == ByteOrder.BigEndian).ifValue(this,this.reversedArray())

fun Array<Byte>.littleEndianTo(byteOrder: ByteOrder) = (byteOrder == ByteOrder.LittleEndian).ifValue(this,this.reversedArray())

fun ByteArray.littleEndianTo(byteOrder: ByteOrder) = (byteOrder == ByteOrder.LittleEndian).ifValue(this,this.reversedArray())

fun ByteArray.updateUseLittleEndian(byteOrder : ByteOrder, startIndex:Int = 0, length:Int = this.size,littleEndianBlock : (index:Int) -> Byte){
    val rage = startIndex until startIndex + length
    val indexRage = (byteOrder == ByteOrder.LittleEndian).ifValue(rage,rage.reversed())
    indexRage.forEachIndexed {index, i ->
        this[i] = littleEndianBlock(index)
    }
}

fun Array<Byte>.updateUseLittleEndian(byteOrder : ByteOrder, startIndex:Int = 0, length:Int = this.size,littleEndianBlock : (index:Int) -> Byte){
    val rage = startIndex until startIndex + length
    val indexRage = (byteOrder == ByteOrder.LittleEndian).ifValue(rage,rage.reversed())
    indexRage.forEachIndexed {index, i ->
        this[i] = littleEndianBlock(index)
    }
}

fun ByteArray.updateUseBigEndian(byteOrder : ByteOrder, startIndex:Int = 0, length:Int = this.size,bigEndianBlock : (index:Int) -> Byte){
    val rage = startIndex until startIndex + length
    val indexRage = (byteOrder == ByteOrder.BigEndian).ifValue(rage,rage.reversed())
    indexRage.forEachIndexed {index, i ->
        this[i] = bigEndianBlock(index)
    }
}

fun Array<Byte>.updateUseBigEndian(byteOrder : ByteOrder, startIndex:Int = 0, length:Int = this.size,bigEndianBlock : (index:Int) -> Byte){
    val rage = startIndex until startIndex + length
    val indexRage = (byteOrder == ByteOrder.BigEndian).ifValue(rage,rage.reversed())
    indexRage.forEachIndexed {index, i ->
        this[i] = bigEndianBlock(index)
    }
}


fun ByteArray.getUseLittleEndian(byteOrder : ByteOrder, startIndex:Int = 0, length:Int = this.size,littleEndianBlock : (index:Int,byte:Byte) -> Unit){
    val rage = startIndex until startIndex + length
    val indexRage = (byteOrder == ByteOrder.LittleEndian).ifValue(rage,rage.reversed())
    indexRage.forEachIndexed {index, i ->
       littleEndianBlock(index,this[i])
    }
}

fun ByteArray.getUseBigEndian(byteOrder : ByteOrder, startIndex:Int = 0, length:Int = this.size,bigEndianBlock : (index:Int,byte:Byte) -> Unit){
    val rage = startIndex until startIndex + length
    val indexRage = (byteOrder == ByteOrder.BigEndian).ifValue(rage,rage.reversed())
    indexRage.forEachIndexed {index, i ->
        bigEndianBlock(index,this[i])
    }
}